import Api, { HttpResponse } from '../../http/Api';
import { tokenInterceptor } from '../Interceptors';
import {
	HttpServiceResponse,
	Model,
	PageInfo,
	QueryAllCondition,
	QueryCondition,
} from './index';

class BaseService<T extends Model> extends Api {
	protected initTokenInstance = (key: string): Api => {
		return this.initSingle(
			key,
			{
				baseURL: `/api/${key}`,
			},
			tokenInterceptor
		) as Api;
	};

	selectOneById = (id: string): Promise<HttpServiceResponse<T>> =>
		this.request({
			method: this.method.GET,
			url: `/id/${id}`,
		});

	selectOne = (record: Partial<T>): Promise<HttpServiceResponse<T>> =>
		this.request({
			method: this.method.POST,
			url: '/search',
			data: record,
		});

	selectByIds = (list: string[]): Promise<HttpServiceResponse<T[]>> =>
		this.request({
			method: this.method.POST,
			url: '/list/id',
			data: list,
		});

	select = (
		condition: QueryCondition<T>
	): Promise<HttpServiceResponse<PageInfo<T>>> =>
		this.request({
			method: this.method.POST,
			url: '/list/search',
			data: condition,
		});

	selectLike = (
		condition: QueryCondition<T>
	): Promise<HttpServiceResponse<PageInfo<T>>> =>
		this.request({
			method: this.method.POST,
			url: '/list/like',
			data: condition,
		});

	selectAll = (
		condition: QueryAllCondition
	): Promise<HttpServiceResponse<PageInfo<T>>> =>
		this.request({
			method: this.method.GET,
			url: '/list',
			data: condition,
		});

	selectCount = (record: Partial<T>): Promise<HttpServiceResponse<number>> =>
		this.request({
			method: this.method.POST,
			url: '/count',
			data: record,
		});

	insert = (record: Partial<T>): Promise<HttpServiceResponse<string>> =>
		this.request({
			method: this.method.POST,
			data: record,
		});

	insertList = (
		records: Partial<T>[]
	): Promise<HttpServiceResponse<string[]>> =>
		this.request({
			method: this.method.POST,
			url: '/list',
			data: records,
		});

	save = (record: Partial<T>): Promise<HttpServiceResponse<string>> =>
		this.request({
			method: this.method.PUT,
			data: record,
		});

	saveList = (records: Partial<T>[]): Promise<HttpServiceResponse<string[]>> =>
		this.request({
			method: this.method.PUT,
			url: '/list',
			data: records,
		});

	update = (record: Partial<T>): Promise<HttpServiceResponse<void>> =>
		this.request({
			method: this.method.PATCH,
			data: record,
		});

	updateList = (records: Partial<T>[]): Promise<HttpServiceResponse<void>> =>
		this.request({
			method: this.method.PATCH,
			url: '/list',
			data: records,
		});

	deleteById = (id: string): Promise<HttpResponse<void>> =>
		this.request({
			method: this.method.DELETE,
			url: `/id/${id}`,
		});

	deleteByIds = (list: string[]): Promise<HttpResponse<void>> =>
		this.request({
			method: this.method.DELETE,
			url: '/list/id',
			data: list,
		});
}

export abstract class DataService<
	S extends BaseService<T>,
	T extends Model
> extends BaseService<T> {
	public constructor() {
		super();
		this.create();
	}

	protected abstract create(): S;
}
